# -*- coding: utf-8 -*-
"""
乒乓球培训管理系统 - 教练控制器

教练管理相关的业务逻辑
包括教练审核、编辑、统计等功能
"""

from datetime import datetime, date, timedelta
from decimal import Decimal
from sqlalchemy import and_, or_, func, desc, asc
from flask_login import current_user

from app import db
from app.models.user import User
from app.models.campus import Campus
from app.models.relation import StudentCoachRelation
from app.models.reservation import Reservation
from app.utils.file_upload import save_uploaded_file


class CoachController:
    """教练控制器"""

    @staticmethod
    def get_coach_list(page=1, per_page=12, keyword=None, campus_id=None,
                      status=None, coach_level=None, sort_by='created_at_desc'):
        """
        获取教练列表

        Args:
            page (int): 页码
            per_page (int): 每页数量
            keyword (str): 搜索关键词
            campus_id (int): 校区ID
            status (str): 状态
            coach_level (str): 教练级别
            sort_by (str): 排序方式

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            # 基础查询
            query = User.query.filter_by(role='coach')

            # 权限过滤
            if current_user.is_campus_admin():
                query = query.filter_by(campus_id=current_user.campus_id)

            # 关键词搜索
            if keyword:
                keyword = f'%{keyword}%'
                query = query.filter(
                    or_(
                        User.real_name.like(keyword),
                        User.phone.like(keyword),
                        User.email.like(keyword),
                        User.username.like(keyword)
                    )
                )

            # 校区筛选
            if campus_id:
                query = query.filter_by(campus_id=campus_id)

            # 状态筛选
            if status:
                query = query.filter_by(status=status)

            # 级别筛选
            if coach_level:
                query = query.filter_by(coach_level=coach_level)

            # 排序
            if sort_by == 'created_at_desc':
                query = query.order_by(desc(User.created_at))
            elif sort_by == 'created_at_asc':
                query = query.order_by(asc(User.created_at))
            elif sort_by == 'name_asc':
                query = query.order_by(asc(User.real_name))
            elif sort_by == 'name_desc':
                query = query.order_by(desc(User.real_name))
            elif sort_by == 'level_desc':
                # 按级别排序：senior > middle > junior
                query = query.order_by(
                    func.field(User.coach_level, 'senior', 'middle', 'junior')
                )
            elif sort_by == 'rate_desc':
                query = query.order_by(desc(User.hourly_rate))
            elif sort_by == 'rate_asc':
                query = query.order_by(asc(User.hourly_rate))

            # 分页
            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            total = query.count()

            return pagination, total

        except Exception as e:
            print(f"Error in get_coach_list: {str(e)}")
            return None, 0

    @staticmethod
    def get_coach_by_id(coach_id):
        """
        根据ID获取教练

        Args:
            coach_id (int): 教练ID

        Returns:
            User: 教练对象或None
        """
        try:
            coach = User.query.filter_by(id=coach_id, role='coach').first()

            # 权限检查
            if coach and current_user.is_campus_admin():
                if coach.campus_id != current_user.campus_id:
                    return None

            return coach

        except Exception as e:
            print(f"Error in get_coach_by_id: {str(e)}")
            return None

    @staticmethod
    def update_coach(coach, form_data):
        """
        更新教练信息

        Args:
            coach (User): 教练对象
            form_data (dict): 表单数据

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            # 权限检查
            if current_user.is_campus_admin() and coach.campus_id != current_user.campus_id:
                return False, "无权限修改此教练信息"

            # 校区权限检查
            new_campus_id = form_data.get('campus_id')
            if current_user.is_campus_admin() and new_campus_id != current_user.campus_id:
                return False, "您只能将教练分配到自己管理的校区"

            # 更新基本信息
            coach.real_name = form_data.get('real_name', coach.real_name)
            coach.phone = form_data.get('phone', coach.phone)
            coach.email = form_data.get('email') or None
            coach.gender = form_data.get('gender') or None
            coach.age = form_data.get('age') or None
            coach.campus_id = new_campus_id
            coach.coach_level = form_data.get('coach_level', coach.coach_level)
            coach.hourly_rate = form_data.get('hourly_rate', coach.hourly_rate)
            coach.bio = form_data.get('bio') or None
            coach.experience = form_data.get('experience') or None
            coach.status = form_data.get('status', coach.status)
            coach.updated_at = datetime.now()

            # 处理头像上传
            photo_file = form_data.get('photo')
            if photo_file:
                photo_url = save_uploaded_file(photo_file, 'coaches')
                if photo_url:
                    coach.photo_url = photo_url

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            return False, f"更新失败：{str(e)}"

    @staticmethod
    def approve_coach(coach_id, form_data):
        """
        审核教练

        Args:
            coach_id (int): 教练ID
            form_data (dict): 表单数据

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            coach = User.query.filter_by(id=coach_id, role='coach').first()
            if not coach:
                return False, "教练不存在"

            if coach.status != 'pending':
                return False, "该教练已经被审核过了"

            # 权限检查
            campus_id = form_data.get('campus_id')
            if current_user.is_campus_admin():
                if campus_id != current_user.campus_id:
                    return False, "您只能审核分配到自己校区的教练"

            action = form_data.get('action')

            if action == 'approve':
                # 通过审核
                coach.status = 'active'
                coach.campus_id = campus_id
                coach.coach_level = form_data.get('coach_level', 'junior')
                coach.hourly_rate = form_data.get('hourly_rate', Decimal('30.00'))
                coach.updated_at = datetime.now()

                # TODO: 发送审核通过通知

            elif action == 'reject':
                # 拒绝审核
                coach.status = 'inactive'
                coach.updated_at = datetime.now()

                # TODO: 发送审核拒绝通知

            else:
                return False, "无效的审核动作"

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            return False, f"审核失败：{str(e)}"

    @staticmethod
    def delete_coach(coach_id):
        """
        删除教练（软删除）

        Args:
            coach_id (int): 教练ID

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            coach = User.query.filter_by(id=coach_id, role='coach').first()
            if not coach:
                return False, "教练不存在"

            # 权限检查
            if current_user.is_campus_admin() and coach.campus_id != current_user.campus_id:
                return False, "无权限删除此教练"

            # 检查是否有关联数据
            associations = CoachController.check_coach_associations(coach_id)
            if associations['has_active_students'] or associations['has_future_reservations']:
                return False, "该教练还有在指导的学员或未来的课程预约，无法删除"

            # 软删除：设置为inactive状态
            coach.status = 'inactive'
            coach.updated_at = datetime.now()

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            return False, f"删除失败：{str(e)}"

    @staticmethod
    def check_coach_associations(coach_id):
        """
        检查教练关联数据

        Args:
            coach_id (int): 教练ID

        Returns:
            dict: 关联数据统计
        """
        try:
            # 活跃学员数
            active_students = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='approved'
            ).count()

            # 未来的预约数
            future_reservations = Reservation.query.filter(
                Reservation.coach_id == coach_id,
                Reservation.status.in_(['pending', 'confirmed']),
                Reservation.reservation_date >= date.today()
            ).count()

            # 总学员数
            total_students = StudentCoachRelation.query.filter_by(
                coach_id=coach_id
            ).count()

            # 总预约数
            total_reservations = Reservation.query.filter_by(
                coach_id=coach_id
            ).count()

            return {
                'has_active_students': active_students > 0,
                'has_future_reservations': future_reservations > 0,
                'active_students_count': active_students,
                'future_reservations_count': future_reservations,
                'total_students_count': total_students,
                'total_reservations_count': total_reservations
            }

        except Exception as e:
            print(f"Error in check_coach_associations: {str(e)}")
            return {
                'has_active_students': False,
                'has_future_reservations': False,
                'active_students_count': 0,
                'future_reservations_count': 0,
                'total_students_count': 0,
                'total_reservations_count': 0
            }

    @staticmethod
    def get_coach_statistics(coach_id):
        """
        获取教练统计信息

        Args:
            coach_id (int): 教练ID

        Returns:
            dict: 统计数据
        """
        try:
            today = date.today()
            week_start = today - timedelta(days=today.weekday())
            month_start = today.replace(day=1)

            # 学员统计
            total_students = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='approved'
            ).count()

            pending_students = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='pending'
            ).count()

            # 预约统计
            today_reservations = Reservation.query.filter(
                Reservation.coach_id == coach_id,
                func.date(Reservation.reservation_date) == today,
                Reservation.status.in_(['confirmed', 'completed'])
            ).count()

            week_reservations = Reservation.query.filter(
                Reservation.coach_id == coach_id,
                Reservation.reservation_date >= week_start,
                Reservation.status.in_(['confirmed', 'completed'])
            ).count()

            month_reservations = Reservation.query.filter(
                Reservation.coach_id == coach_id,
                Reservation.reservation_date >= month_start,
                Reservation.status.in_(['confirmed', 'completed'])
            ).count()

            # 收入统计
            today_revenue = db.session.query(func.sum(Reservation.price)).filter(
                Reservation.coach_id == coach_id,
                func.date(Reservation.reservation_date) == today,
                Reservation.status.in_(['completed'])
            ).scalar() or Decimal('0')

            week_revenue = db.session.query(func.sum(Reservation.price)).filter(
                Reservation.coach_id == coach_id,
                Reservation.reservation_date >= week_start,
                Reservation.status.in_(['completed'])
            ).scalar() or Decimal('0')

            month_revenue = db.session.query(func.sum(Reservation.price)).filter(
                Reservation.coach_id == coach_id,
                Reservation.reservation_date >= month_start,
                Reservation.status.in_(['completed'])
            ).scalar() or Decimal('0')

            # 课时统计
            total_hours = db.session.query(func.sum(Reservation.duration_minutes)).filter(
                Reservation.coach_id == coach_id,
                Reservation.status == 'completed'
            ).scalar() or 0

            # 评价统计（如果有评价模型的话）
            # 这里先简单返回，后续可以补充
            avg_rating = 4.5  # 暂时固定值
            total_reviews = 0

            return {
                'total_students': total_students,
                'pending_students': pending_students,
                'today_reservations': today_reservations,
                'week_reservations': week_reservations,
                'month_reservations': month_reservations,
                'today_revenue': float(today_revenue),
                'week_revenue': float(week_revenue),
                'month_revenue': float(month_revenue),
                'total_hours': round(total_hours / 60, 1) if total_hours else 0,
                'avg_rating': avg_rating,
                'total_reviews': total_reviews
            }

        except Exception as e:
            print(f"Error in get_coach_statistics: {str(e)}")
            return {
                'total_students': 0,
                'pending_students': 0,
                'today_reservations': 0,
                'week_reservations': 0,
                'month_reservations': 0,
                'today_revenue': 0,
                'week_revenue': 0,
                'month_revenue': 0,
                'total_hours': 0,
                'avg_rating': 0,
                'total_reviews': 0
            }

    @staticmethod
    def get_coach_students(coach_id):
        """
        获取教练的学员列表

        Args:
            coach_id (int): 教练ID

        Returns:
            list: 学员关系列表
        """
        try:
            relations = StudentCoachRelation.query.filter_by(
                coach_id=coach_id
            ).order_by(desc(StudentCoachRelation.applied_at)).all()

            return relations

        except Exception as e:
            print(f"Error in get_coach_students: {str(e)}")
            return []

    @staticmethod
    def get_coach_recent_reservations(coach_id, limit=10):
        """
        获取教练最近的预约记录

        Args:
            coach_id (int): 教练ID
            limit (int): 限制数量

        Returns:
            list: 预约列表
        """
        try:
            reservations = Reservation.query.filter_by(
                coach_id=coach_id
            ).order_by(desc(Reservation.reservation_date), desc(Reservation.start_time)).limit(limit).all()

            return reservations

        except Exception as e:
            print(f"Error in get_coach_recent_reservations: {str(e)}")
            return []

    @staticmethod
    def batch_operation(coach_ids, action, **kwargs):
        """
        批量操作教练

        Args:
            coach_ids (list): 教练ID列表
            action (str): 操作类型
            **kwargs: 其他参数

        Returns:
            tuple: (成功数量, 失败数量, 错误列表)
        """
        try:
            success_count = 0
            fail_count = 0
            errors = []

            for coach_id in coach_ids:
                try:
                    coach = User.query.filter_by(id=coach_id, role='coach').first()
                    if not coach:
                        errors.append(f"教练ID {coach_id} 不存在")
                        fail_count += 1
                        continue

                    # 权限检查
                    if current_user.is_campus_admin() and coach.campus_id != current_user.campus_id:
                        errors.append(f"无权限操作教练 {coach.real_name}")
                        fail_count += 1
                        continue

                    if action == 'activate':
                        coach.status = 'active'
                    elif action == 'deactivate':
                        coach.status = 'inactive'
                    elif action == 'set_level':
                        target_level = kwargs.get('target_level')
                        if target_level:
                            coach.coach_level = target_level
                    elif action == 'transfer_campus':
                        target_campus_id = kwargs.get('target_campus_id')
                        if target_campus_id:
                            # 权限检查
                            if current_user.is_campus_admin() and target_campus_id != current_user.campus_id:
                                errors.append(f"无权限将教练 {coach.real_name} 转移到其他校区")
                                fail_count += 1
                                continue
                            coach.campus_id = target_campus_id
                    elif action == 'delete':
                        associations = CoachController.check_coach_associations(coach_id)
                        if associations['has_active_students'] or associations['has_future_reservations']:
                            errors.append(f"教练 {coach.real_name} 还有关联数据，无法删除")
                            fail_count += 1
                            continue
                        coach.status = 'inactive'

                    coach.updated_at = datetime.now()
                    success_count += 1

                except Exception as e:
                    errors.append(f"操作教练ID {coach_id} 时出错：{str(e)}")
                    fail_count += 1

            db.session.commit()
            return success_count, fail_count, errors

        except Exception as e:
            db.session.rollback()
            return 0, len(coach_ids), [f"批量操作失败：{str(e)}"]

    @staticmethod
    def get_pending_coaches_count():
        """
        获取待审核教练数量

        Returns:
            int: 待审核数量
        """
        try:
            query = User.query.filter_by(role='coach', status='pending')

            # 权限过滤
            if current_user.is_campus_admin():
                query = query.filter_by(campus_id=current_user.campus_id)

            return query.count()

        except Exception as e:
            print(f"Error in get_pending_coaches_count: {str(e)}")
            return 0

    @staticmethod
    def get_campus_coach_summary(campus_id=None):
        """
        获取校区教练汇总统计

        Args:
            campus_id (int): 校区ID，None表示全部

        Returns:
            dict: 汇总统计
        """
        try:
            query = User.query.filter_by(role='coach')

            # 权限过滤
            if current_user.is_campus_admin():
                query = query.filter_by(campus_id=current_user.campus_id)
            elif campus_id:
                query = query.filter_by(campus_id=campus_id)

            # 总数统计
            total = query.count()
            active = query.filter_by(status='active').count()
            pending = query.filter_by(status='pending').count()
            inactive = query.filter_by(status='inactive').count()

            # 级别统计
            senior = query.filter_by(coach_level='senior').count()
            middle = query.filter_by(coach_level='middle').count()
            junior = query.filter_by(coach_level='junior').count()

            return {
                'total': total,
                'active': active,
                'pending': pending,
                'inactive': inactive,
                'senior': senior,
                'middle': middle,
                'junior': junior
            }

        except Exception as e:
            print(f"Error in get_campus_coach_summary: {str(e)}")
            return {
                'total': 0,
                'active': 0,
                'pending': 0,
                'inactive': 0,
                'senior': 0,
                'middle': 0,
                'junior': 0
            }